﻿using EntityFramework.Data.Core;
using Framework.Common;
using Framework.Common.Paged;
using IRepositories.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using YouTravel.DomainModels;
using YouTravel.Framework.Const;
using YouTravel.Framework.Enums;
using YouTravel.QueryModels;
using YouTravel.ViewModels;
using System.Data.Entity;
using Framework.Common.Exceptions;
using YouTravel.Framework.ResourceMessage;

namespace YouTravel.DomainService
{
	public class ContractService : IContractService
	{
	    readonly IEFRepository<Special> _specialRepository;
	    readonly IEFRepository<Contract> _contractRepository;
	    readonly IEFRepository<SellerSupplier> _sellersupplierRepository;
	    readonly IUnitOfWork _db;
		public ContractService(IUnitOfWork db, IEFRepository<Contract> contractRepository, IEFRepository<SellerSupplier> sellersupplierRepository, IEFRepository<Special> specialRepository)
		{
			this._db = db;
			this._contractRepository = contractRepository;
			this._sellersupplierRepository = sellersupplierRepository;
			this._specialRepository = specialRepository;
			this._contractRepository.SetDbContext(this._db);
			this._sellersupplierRepository.SetDbContext(this._db);
			this._specialRepository.SetDbContext(this._db);
		}

		/// <summary>
		/// 专线合同列表页面 Pwp 2015-09-21
		/// </summary>
		/// <param name="queryCond"></param>
		/// <returns></returns>
		public CustomPagedList<ContractListViewModel> GetBranchList(PagedParam<SpecialContractQuery> queryCond)
		{
			return _contractRepository.GetModel(o => o.Status == ContractStatus.Normal || o.Status == ContractStatus.Renewal)
				.Where(o => o.Type == ContractType.SpecialLine)//专线合同
				.Include(p => p.Attachments)
				.Include(p => p.Special)
                .GetPagedList(queryCond.PageDto.PageNo,
				queryCond.PageDto.PageSize, BuildContractQuery(queryCond.QueryDto),
				queryCond.SortField).ToCustomPagedList<Contract, ContractListViewModel>((u) =>
                {
					var s = u.MapNew<Contract, ContractListViewModel>();
					//s.Name = u.Name
                    return s;
                });
		}

		/// <summary>
		/// 专线合同筛选条件
		/// </summary>
		/// <param name="specialcontractQuery"></param>
		/// <returns></returns>
		private Func<IQueryable<Contract>, IQueryable<Contract>> BuildContractQuery(SpecialContractQuery specialcontractQuery)
		{
			return (query) =>
			{
				if (specialcontractQuery != null)
				{
					if (specialcontractQuery.BranchId != 0)
						query = query.Where(p => p.BranchId == specialcontractQuery.BranchId);
					if (!string.IsNullOrEmpty(specialcontractQuery.SpecialName))
						query = query.Where(p => p.Special.Name.Contains(specialcontractQuery.SpecialName));
					if (specialcontractQuery.StartTime.HasValue)
					{
						DateTime start = specialcontractQuery.StartTime.Value.Date;
						query = query.Where(p => p.EndDate >= start);
					}
					if (specialcontractQuery.EndTime.HasValue)
					{
						DateTime end = specialcontractQuery.EndTime.Value.AddDays(1).Date;
						query = query.Where(p => p.EndDate < end);
					}
				}
				return query;
			};
		}

		/// <summary>
		/// 续约专线合同 Pwp 2015-09-22
		/// </summary>
		/// <param name="_branchview"></param>
		/// <returns></returns>
		public void RenewalContract(ContractViewModel contractview)
		{
			//更新原合同为关闭
			Contract mOldContract = _contractRepository.GetModelTracking().Where(o => o.ID == contractview.ID).FirstOrDefault();
			if(mOldContract == null)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemNotFound, "原合同单"));

			//新合同创建
			Contract mNewContract = new Contract();
			mNewContract.Name = contractview.ContractName;
			mNewContract.Code = CommonMethod.GetInstance.GenerateCode("YTHT");
			mNewContract.Type = ContractType.SpecialLine;
			mNewContract.Status = ContractStatus.Renewal;
			//mNewContract.StartDate = mOldContract.StartDate;
			mNewContract.EndDate = DateTime.Parse(contractview.EndDate);
			mNewContract.CreaterId = contractview.OperatorID;
			mNewContract.CreateTime = contractview.OptionTime;
			mNewContract.UpdaterId = contractview.OperatorID;
			mNewContract.UpdateTime = contractview.OptionTime;
			if (mOldContract.BranchId!=null)
			mNewContract.BranchId = mOldContract.BranchId;
			if (mOldContract.SpecialId != null)
			mNewContract.SpecialId = mOldContract.SpecialId;
			if (mOldContract.SellerSupplierId != null)
			mNewContract.SellerSupplierId = mOldContract.SellerSupplierId;

			List<Attachment> lstAttachment = new List<Attachment>();
			foreach (ContractAttachment temp in contractview.Attachments)
			{
				Attachment mAttachment = new Attachment();
				mAttachment.Name = temp.Item1;
				mAttachment.Type = AttachmentType.ContractAttachment;
				mAttachment.Address = temp.Item2;
				string suffix = "";
				string[] arrName = temp.Item1.Split('.');
				if (arrName.Length > 1)
				{
					suffix = "." + arrName[arrName.Length - 1];
				}
				mAttachment.Suffix = suffix;
				mAttachment.CreateTime = contractview.OptionTime;
				lstAttachment.Add(mAttachment);
			}
			mNewContract.Attachments = lstAttachment;

			TransactionScopeNoMsdtc.UsingTransactionNoMsdtc(_db, () =>
			{
				_contractRepository.Update(x => x.ID == contractview.ID, u => new Contract
				{
					Status = ContractStatus.Close
				});
				_contractRepository.Insert(mNewContract);
				_specialRepository.Update(x => x.ID == mOldContract.SpecialId, u => new Special
				{
					EndDate = DateTime.Parse(contractview.EndDate)
				});
			});
		}

		/// <summary>
		/// 供应商/销售商列表页面 Pwp 2015-09-23
		/// </summary>
		/// <param name="queryCond"></param>
		/// <returns></returns>
		public CustomPagedList<ContractListViewModel> GetSellerSupplierList(PagedParam<SpecialContractQuery> queryCond)
		{
			return _contractRepository.GetModel()
				.Where(o => o.Type == queryCond.QueryDto.Type)//专线合同
				.Include(p => p.Attachments)
				.Include(p => p.SellerSupplier)
				.GetPagedList(queryCond.PageDto.PageNo,
				queryCond.PageDto.PageSize, BuildSellerSupplierQuery(queryCond.QueryDto),
				queryCond.SortField).ToCustomPagedList<Contract, ContractListViewModel>((u) =>
				{
					var s = u.MapNew<Contract, ContractListViewModel>();
					//s.Name = u.Name
					return s;
				});
		}

		/// <summary>
		/// 供应商/销售商筛选条件 Pwp 2015-09-23
		/// </summary>
		/// <param name="specialcontractQuery"></param>
		/// <returns></returns>
		private Func<IQueryable<Contract>, IQueryable<Contract>> BuildSellerSupplierQuery(SpecialContractQuery specialcontractQuery)
		{
			return (query) =>
			{
				if (specialcontractQuery != null)
				{
					if(specialcontractQuery.SpecialId != 0)
						query = query.Where(p => p.SpecialId == specialcontractQuery.SpecialId);
					if (!string.IsNullOrEmpty(specialcontractQuery.SpecialName))
						query = query.Where(p => p.Name.Contains(specialcontractQuery.SpecialName));
				}
				return query;
			};
		}

		/// <summary>
		/// 废弃/恢复合同 Pwp 2015-09-23
		/// </summary>
		/// <param name="sellersuppliermodel"></param>
		/// <returns></returns>
		public void AbandonedContract(SellerSupplier sellersuppliermodel)
		{
			_sellersupplierRepository.Update(x => x.ID == sellersuppliermodel.ID, u => new SellerSupplier
			{
				Status = sellersuppliermodel.Status,
				UpdaterId = sellersuppliermodel.UpdaterId,
				UpdateTime = sellersuppliermodel.UpdateTime
			});
		}

		/// <summary>
		/// 创建供应商合同 Pwp 2015-09-23
		/// </summary>
		/// <param name="contractview"></param>
		/// <returns></returns>
		public void AddContract(ContractViewModel contractview)
		{
			string strNameType = "供应商";
			if (contractview.Type == (int)SellerSupplierType.Seller)
				strNameType = "销售商";
			//更新原合同为关闭
			if ( _contractRepository.GetModel()
				.Include(p => p.SellerSupplier)
				.Any(o => o.SpecialId == contractview.SpecialId && o.SellerSupplier.Name == contractview.Name && o.SellerSupplier.Type == (SellerSupplierType)contractview.Type))
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemBeenHade, strNameType+"合同名称"));

			//供应商销售商集合
			SellerSupplier mSellerSupplier = new SellerSupplier();
			mSellerSupplier.Name = contractview.Name;
			mSellerSupplier.Type = (SellerSupplierType)contractview.Type;
			mSellerSupplier.Status = Convert.ToBoolean((int)SellerSupplierStatus.Normal);
			mSellerSupplier.Phone = contractview.Phone;
			mSellerSupplier.ChargeBankNumber = contractview.ChargeBankNumber;
			mSellerSupplier.Bank = contractview.Bank;
			mSellerSupplier.ChargeName = contractview.ChargeName;
			mSellerSupplier.CertificateNum =  contractview.CertificateNum;
			mSellerSupplier.CreaterId = contractview.OperatorID;
			mSellerSupplier.CreateTime = contractview.OptionTime;
			mSellerSupplier.UpdaterId = contractview.OperatorID;
			mSellerSupplier.UpdaterName = contractview.OperatorName;
			mSellerSupplier.UpdateTime = contractview.OptionTime;

			TransactionScopeNoMsdtc.UsingTransactionNoMsdtc(_db, () =>
			{
				_sellersupplierRepository.Insert(mSellerSupplier);
				Contract mNewContract = new Contract();
				mNewContract.Name = contractview.ContractName;
				mNewContract.Code = CommonMethod.GetInstance.GenerateCode("YTHT");

				mNewContract.Type = ContractType.Supplier;
				if (contractview.Type == (int)SellerSupplierType.Seller)
					mNewContract.Type = ContractType.Seller;
				mNewContract.Status = ContractStatus.Normal;
				//mNewContract.StartDate = DateTime.Parse(_contractview.StartDate);
				mNewContract.EndDate = DateTime.Parse(contractview.EndDate);
				mNewContract.CreaterId = contractview.OperatorID;
				mNewContract.CreateTime = contractview.OptionTime;
				mNewContract.UpdaterId = contractview.OperatorID;
				mNewContract.UpdateTime = contractview.OptionTime;
				mNewContract.SpecialId = contractview.SpecialId;
				mNewContract.SellerSupplierId = mSellerSupplier.ID;

				List<Attachment> lstAttachment = new List<Attachment>();
				foreach (ContractAttachment temp in contractview.Attachments)
				{
					Attachment mAttachment = new Attachment();
					mAttachment.Name = temp.Item1;
					mAttachment.Type = AttachmentType.ContractAttachment;
					mAttachment.Address = temp.Item2;
					string suffix = "";
					string[] arrName = temp.Item1.Split('.');
					if (arrName.Length > 1)
					{
						suffix = "."+arrName[arrName.Length - 1];
					}
					mAttachment.Suffix = suffix;
					mAttachment.CreateTime = contractview.OptionTime;
					lstAttachment.Add(mAttachment);
				}
				mNewContract.Attachments = lstAttachment;
				_contractRepository.Insert(mNewContract);
			});
		}
	}
}
